Skip to content

feat(devcontainer): base on Ubuntu 26.04 and add Claude Code CLI#44

Open
idvoretskyi wants to merge 7 commits into
mainfrom
feat/ubuntu-26.04-claude-code
Open

feat(devcontainer): base on Ubuntu 26.04 and add Claude Code CLI#44
idvoretskyi wants to merge 7 commits into
mainfrom
feat/ubuntu-26.04-claude-code

Conversation

@idvoretskyi

Copy link
Copy Markdown
Owner

Summary

Bumps the devcontainer base to Ubuntu 26.04 (Resolute) and embeds Claude Code CLI as a first-class devcontainer feature, along with a full CI consolidation and codebase-wide review fixes.

Changes

Devcontainer

  • Ubuntu 26.04: mcr.microsoft.com/devcontainers/base:ubuntu26.04 (MCR dropped the hyphen at 26.04+; tag verified published and multi-arch)
  • Claude Code CLI: added via ghcr.io/anthropics/devcontainer-features/claude-code:1.0
  • Persistent auth: named volume claude-code-config-${devcontainerId} mounted at /home/vscode/.claude — auth and settings survive container rebuilds
  • anthropic.claude-code VS Code extension added to the extensions list
  • devcontainer-lock.json: SHA-pinned digests for all 5 features (supply-chain equivalent of package-lock.json)

CI (ci.yml replaces security.yml)

  • Merged security.yml into ci.yml; single workflow with build → test → scan jobs sharing one Docker image via artifact (docker save/load), eliminating the duplicate build that ran on every push
  • Added schedule (daily 02:00 UTC) and workflow_dispatch triggers (migrated from security.yml)
  • Removed unused actions: read permission; per-job permission grants instead
  • All three SARIF uploads now guarded against fork PRs (read-only token → 403 was a hard failure)
  • Added claude to smoke-test binary loop and version assertions
  • Trivy now gates on CRITICAL (exit-code: 1) for both image and filesystem scans, consistent with gitleaks which already gated on secrets

Dependabot

  • All three ecosystems changed from weekly → daily (supply-chain and CVE exposure warrants daily checks)
  • Added devcontainers ecosystem block (was missing) — node, github-cli, common-utils, sshd, and claude-code features now receive update PRs
  • Raised open-pull-requests-limit to 10

Docs

  • README: updated for Ubuntu 26.04, Claude Code tooling and extension, fixed stale feature list and jq/curl provenance claims, reflects merged CI workflow
  • AGENTS.md: new contributor/agent guidance file — project overview, file layout, commit conventions, JSON and Actions pinning rules, local validation commands, guardrails

Test results (local, pre-commit)

Stage Result
JSON validity (devcontainer.json)
hadolint
docker build --pull (ubuntu26.04)
Devcontainer smoke test (all 8 binaries)

Smoke test output:

OK: python3  OK: node  OK: npm  OK: gh  OK: opencode  OK: curl  OK: jq  OK: claude
Python 3.14.4 / Node v24.18.0 / npm 11.16.0 / gh 2.95.0 / opencode 1.17.11 / claude 2.1.193

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the devcontainer template to Ubuntu 26.04 and adds Claude Code (feature + VS Code extension), while consolidating CI/security scanning into a single workflow and tightening dependency update automation/documentation.

Changes:

  • Bump devcontainer base image to mcr.microsoft.com/devcontainers/base:ubuntu26.04 and add Claude Code CLI with persisted auth volume + extension.
  • Consolidate security workflow into ci.yml with build→test→scan jobs sharing a built Docker image via artifact; gate Trivy on CRITICAL; skip SARIF uploads on fork PRs.
  • Switch Dependabot schedules to daily and add a devcontainers ecosystem block; add AGENTS.md contributor/agent guidance and refresh README.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
README.md Updates documented features/tooling and workflow references for Ubuntu 26.04 + Claude Code + consolidated CI.
AGENTS.md Adds repo conventions/guardrails and local validation guidance for contributors and automation.
.github/workflows/security.yml Removes standalone security workflow now merged into CI.
.github/workflows/ci.yml Adds schedule/dispatch triggers, splits build/test/scan, shares Docker image via artifact, and tightens SARIF upload conditions.
.github/dependabot.yml Moves updates to daily cadence and adds devcontainer feature update tracking.
.devcontainer/Dockerfile Switches devcontainer base image to Ubuntu 26.04 tag.
.devcontainer/devcontainer.json Adds Claude Code feature, persists its config via volume mount, and adds the VS Code extension.
.devcontainer/devcontainer-lock.json Introduces digest-pinned feature lockfile for reproducible devcontainer feature installs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/ci.yml
Comment on lines +134 to +136
- name: Download image artifact
uses: actions/download-artifact@v4
with:
Comment thread README.md Outdated
idvoretskyi added a commit that referenced this pull request Jun 26, 2026
- Pin actions/download-artifact@v4 to full commit SHA
  d3f86a106a0bac45b974a628896c90dbdf5c8093 (v4.3.0), per repo convention
  that all uses: entries must reference a 40-char SHA (AGENTS.md)
- Fix README.md: dependabot.yml now runs daily, not weekly

Addresses Copilot review comments on PR #44.

Signed-off-by: Ihor <ihor@linux.com>
- Bump base image to mcr.microsoft.com/devcontainers/base:ubuntu26.04
  (MCR dropped the hyphen for 26.04+; tag verified published and multi-arch)
- Add ghcr.io/anthropics/devcontainer-features/claude-code:1.0 feature
- Add anthropic.claude-code VS Code extension
- Mount named volume claude-code-config-${devcontainerId} at
  /home/vscode/.claude so auth and settings survive container rebuilds
- Add devcontainer-lock.json with SHA-pinned digests for all 5 features

CI (ci.yml, replaces security.yml):
- Merge security.yml into ci.yml; single workflow with build/test/scan jobs
  sharing one Docker image via artifact (docker save/load), eliminating the
  duplicate build that ran on every push
- Add schedule (daily 02:00 UTC) and workflow_dispatch triggers
- Remove unused actions:read permission; use per-job permission grants
- Guard all SARIF uploads against fork PRs (read-only token -> 403)
- Add claude to smoke-test binary loop and version assertions
- Trivy now gates on CRITICAL (exit-code: 1) for both image and fs scans,
  consistent with gitleaks which already gated on secrets

Dependabot:
- Change all three ecosystems (github-actions, docker, devcontainers) from
  weekly to daily — supply-chain and CVE exposure warrants daily checks
- Add devcontainers ecosystem block (was missing) so node, github-cli,
  common-utils, sshd, and claude-code features receive update PRs
- Raise open-pull-requests-limit to 10 for all ecosystems

Docs:
- Update README: Ubuntu 26.04, Claude Code tooling + extension, fix stale
  feature list and jq/curl provenance claims, reflect merged CI workflow,
  add AGENTS.md to repository structure
- Add AGENTS.md: project overview, file layout, commit conventions, JSON
  and GitHub Actions pinning rules, local validation commands, guardrails

Tested locally: JSON validity, hadolint, docker build (ubuntu26.04),
and full devcontainer smoke test (python3 node npm gh opencode curl jq claude
all present; claude --version: 2.1.193).

Signed-off-by: Ihor <ihor@linux.com>
- Pin actions/download-artifact@v4 to full commit SHA
  d3f86a106a0bac45b974a628896c90dbdf5c8093 (v4.3.0), per repo convention
  that all uses: entries must reference a 40-char SHA (AGENTS.md)
- Fix README.md: dependabot.yml now runs daily, not weekly

Addresses Copilot review comments on PR #44.

Signed-off-by: Ihor <ihor@linux.com>
Both Trivy scan steps now use continue-on-error: true with step IDs,
so SARIF uploads, SBOM generation, and the fs scan all run to completion
even when the image scan finds a CRITICAL vulnerability. A final
explicit failure step gates the job on either scan's outcome.

Previously, exit-code: 1 on the image scan caused the job to abort
before the fs scan ran, which then caused the fs SARIF upload to fail
with 'Path does not exist: trivy-fs-results.sarif'.

Signed-off-by: Ihor <ihor@linux.com>
Suppresses CRITICAL findings where no fixed version is available in the
distro. Unpatched OS-level CVEs (e.g. kernel/stdlib) fluctuate between
CRITICAL and unresolvable depending on the Trivy DB snapshot in the
daily cache, causing spurious failures. This gates only on actionable
findings — vulnerabilities with an available fix.

Signed-off-by: Ihor <ihor@linux.com>
The daily cache-trivy-YYYY-MM-DD key can persist a Trivy DB snapshot
from earlier in the day that contains CVE entries since reclassified or
patched. cache: false ensures each scan downloads the current DB,
giving consistent results regardless of when the runner picks up the
cached artifact.

Signed-off-by: Ihor <ihor@linux.com>
When format: sarif, trivy-action builds the SARIF with all severities
first (ignoring the severity filter) and runs a second exit-code check.
limit-severities-for-sarif: true makes both passes consistent so that
ignore-unfixed is respected in the exit-code determination, not just
in the SARIF output.

Signed-off-by: Ihor <ihor@linux.com>
@idvoretskyi idvoretskyi force-pushed the feat/ubuntu-26.04-claude-code branch from 5dd10fa to 5d5d279 Compare June 30, 2026 09:45
/usr/bin/pebble is an ACME/TLS test server baked into the upstream base
image (mcr.microsoft.com/devcontainers/base:ubuntu26.04). It is not
owned by any apt package, has no systemd unit, and is never invoked at
runtime — it is dead weight.

Its outdated Go runtime (golang.org/x/net v0.40.0, golang.org/x/sys
v0.33.0, stdlib v1.26.2) is the sole source of all fixable HIGH
vulnerabilities in the image (14 CVEs including CVE-2026-25680,
CVE-2026-27145, CVE-2026-33811, CVE-2026-42504, and others). Removing
the binary and its data directory eliminates all of them.

Verified with Trivy v0.71.2:
  Before: 14 fixable HIGH, 1 fixable UNKNOWN (all from usr/bin/pebble)
  After:  0 fixable HIGH, 0 fixable UNKNOWN

The upstream base image scan (sha256:d1fc409b...) confirms the same
root cause: pebble is the only source of fixable HIGH CVEs there too.

Signed-off-by: Ihor <ihor@linux.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants